package m.common.action;

import m.appserver.AuthInfoUtil;
import m.appserver.RequestUtil;
import m.appserver.ResponseUtil;
import m.appserver.ServerResultStatus;
import m.common.dao.Dao;
import m.common.model.UserModel;
import m.common.model.util.ModelUpdateUtil;
import m.common.service.HostInfoService;
import m.common.service.Service;
import m.html.util.HtmlUtil;
import m.system.RuntimeData;
import m.system.exception.MException;
import m.system.util.GenerateID;
import m.system.util.JSONMessage;
import m.system.util.ObjectUtil;
import m.system.util.SystemUtil;
import manage.model.ActionLog;
import manage.model.ActionLogUser;
import manage.model.OrgGroupView;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


public abstract class Action {
	/** 覆盖方法 不受定义事务影响
	 * 此方法可以覆盖，action执行前先执行此方法，用于action执行前的操作
	 */
	public void beforeExecute() throws Exception{

	}

	/**
	 * 覆盖方法 不受定义事务影响  action报错不执行
	 * 此方法可以覆盖，action执行后执行此方法，用于action执行后的操作
	 * 参数是action执行后的返回结果
	 */
	public void afterExecute(Object result) throws Exception{

	}
	/**
	 * 覆盖方法 action报错执行  返回新的结果
	 * 此方法可以覆盖，action执行报错后执行此方法，可改变返回结果
	 * e是action报错后的异常  returnType是action方法返回的类型
	 */
	public Object exceptionExecute(Exception e,ActionResultType returnType) throws Exception {
		throw e;
	}
	/**
	 * 获取当前操作员
	 * 
	 */
	public UserModel getSessionLogUser(){
		return null;
	}
	public OrgGroupView getSessionOrgGroup(){
		return null;
	}

	/**
	 * 返回当前类的action路径
	 */
	public String actionUrl(){
		return actionUrl(this.getClass());
	}
	/**
	 * 返回当前类的action路径
	 */
	public String actionUrl(Class<? extends Action> clazz){
		return HtmlUtil.actionUrl(clazz);
	}
	/**
	 * 返回当前类的action路径+method
	 */
	public String actionUrl(String method){
		return actionUrl(this.getClass(),method);
	}
	/**
	 * 返回当前类的action路径+method
	 */
	public String actionUrl(Class<? extends Action> clazz,String method){
		return HtmlUtil.actionUrl(clazz)+"/"+method;
	}
	/**
	 * 获取service实例
	 *  <T>
	 *  clazz
	 * 
	 *  MException
	 */
	public <T extends Service> T getService(Class<? extends T> clazz) throws MException{
		return RuntimeData.getService(clazz);
	}
	/**
	 * 获取dao实例
	 *  <T>
	 *  clazz
	 * 
	 *  MException
	 */
	public <T extends Dao> T getDao(Class<? extends T> clazz) throws MException{
		return RuntimeData.getDao(clazz);
	}
	public Dao getDao() throws MException{
		return RuntimeData.getDao(Dao.class);
	}
	public Service getService() throws MException{
		return RuntimeData.getService(Service.class);
	}
	private ActionLog log;

	/**
	 * 必须记录日志
	 */
	public void mustLog(String title,String description){
		if(null==log) toLog("C",title,description,"");
	}
	/**
	 * 系统日志记录
	 */
	public void systemLog(String title,String description){
		toLog("A",title,description,null);
	}
	/**
	 * 日志记录
	 */
	public void log(String title,String description){
		log(title,description,null);
	}

	/**
	 * 日志记录
	 */
	public void log(String title,String description,String businessOid){
		toLog("B",title,description,businessOid);
	}
	/**
	 * 日志记录
	 */
	private void toLog(String type,String title,String description,String businessOid){
		log=new ActionLog();
		log.setRequestIp(getRequest().getIpAddress());
		log.setUserAgent(getRequest().getHeader("User-Agent"));
		log.setCreateDate(new Date());
		log.setOid(GenerateID.generatePrimaryKey());
		log.setBusiness(type);
		log.setTitle(title);
		log.setDescription(description);
		log.setBusinessOid(businessOid);
		log.setHost(request.getHeader("host"));
		log.setPath(request.getUri());
		UserModel model=getSessionLogUser();
		if(null!=model) {
			log.setUser(new ActionLogUser());
			log.getUser().setOid(model.getOid());
		}
		OrgGroupView dept=getSessionOrgGroup();
		if(null!=dept){
			log.setDept(dept);
		}
		log.setReadText(getRequestBody());
		try {
			ModelUpdateUtil.insertModel(log);
		} catch (MException e) {
			SystemUtil.println("日志创建失败，但不影响操作！log:",log);
			log=null;
		}
	}
	public void logBusiness(String businessOid){
		if(null!=log){
			log.setBusinessOid(businessOid);
		}
	}
	/** 自动调用，调用则手动记录
	 * 结束日志记录
	 */
	public void endLog(ServerResultStatus status, String backText){
		if(null!=log){
			if(ObjectUtil.isEmptyOid(log.getUser())) {
				UserModel model = getSessionLogUser();
				if (null != model) {
					log.setUser(new ActionLogUser());
					log.getUser().setOid(model.getOid());
				}
			}
			log.setBackText(backText);
			log.setStatus(status.toString());
			log.setProcessTime(new Long(new Date().getTime()-log.getCreateDate().getTime()).intValue());
			try {
				ModelUpdateUtil.updateModel(log,"user.oid","backText","status","processTime");
			} catch (MException e) {
				SystemUtil.println("日志更新失败，但不影响操作！log:",log);
			}
			log=null;
		}
	}
	public static void directLog(String title,String description,String path,String readText,Exception e){
		ActionLog log=new ActionLog();
		log.setRequestIp(HostInfoService.getCurrentHost().getIpport());
		log.setUserAgent("服务器");
		log.setCreateDate(new Date());
		log.setOid(GenerateID.generatePrimaryKey());
		log.setBusiness("C");
		log.setTitle(title);
		log.setDescription(description);
		log.setHost(HostInfoService.getCurrentHost().getIpport());
		log.setPath(path);
		log.setReadText(readText);
		JSONMessage json=new JSONMessage();
		json.push("error",e.getMessage());
		List<String> lines=new ArrayList<>();
		for(StackTraceElement ele : e.getStackTrace()){
			lines.add(ele.getClassName()+"."+ele.getMethodName()+" at "+ele.getLineNumber());
		}
		json.push("lines",lines);
		log.setBackText(json.toJSONString());
		log.setStatus(ServerResultStatus.EXCEPTION.toString());
		log.setProcessTime(0);
		try {
			ModelUpdateUtil.insertModel(log);
		} catch (MException ex) {
			SystemUtil.println("日志创建失败，但不影响操作！log:",log);
		}
	}
	public static void directLog(String title,String description,RequestUtil request,Exception e){
		ActionLog log=new ActionLog();
		log.setRequestIp(request.getIpAddress());
		log.setUserAgent(request.getHeader("User-Agent"));
		log.setCreateDate(new Date());
		log.setOid(GenerateID.generatePrimaryKey());
		log.setBusiness("C");
		log.setTitle(title);
		log.setDescription(description);
		log.setHost(request.getHeader("host"));
		log.setPath(request.getUri());
		UserModel model= AuthInfoUtil.getSessionAdmin();
		if(null!=model) {
			log.setUser(new ActionLogUser());
			log.getUser().setOid(model.getOid());
		}
		log.setReadText(request.getRequestBody());
		JSONMessage json=new JSONMessage();
		json.push("error",e.getMessage());
		List<String> lines=new ArrayList<>();
		for(StackTraceElement ele : e.getStackTrace()){
			lines.add(ele.getClassName()+"."+ele.getMethodName()+" at "+ele.getLineNumber());
		}
		json.push("lines",lines);
		log.setBackText(json.toJSONString());
		log.setStatus(ServerResultStatus.EXCEPTION.toString());
		log.setProcessTime(0);
		try {
			ModelUpdateUtil.insertModel(log);
		} catch (MException ex) {
			SystemUtil.println("日志创建失败，但不影响操作！log:",log);
		}
	}
	
	
	private RequestUtil request;
	private ResponseUtil response;
	private String authorization;
	private Map<String,File> fileMap;
	public String getAuthorization() {
		return authorization;
	}
	public void setAuthorization(String authorization) {
		this.authorization = authorization;
	}
	/**
	 * 获取上传文件流的Map
	 * 
	 */
	public Map<String, File> getFileMap() {
		return fileMap;
	}
	public void setFileMap(Map<String, File> fileMap) {
		this.fileMap = fileMap;
	}

	public String getRequestBody() {
		return request.getRequestBody();
	}
	public String getIpAddress() { 
		return getIpAddress(request);
	}
	public static String getIpAddress(RequestUtil req) {
		return req.getIpAddress();
	}
	public RequestUtil getRequest() {
		return request;
	}
	public void setRequest(RequestUtil request) {
		this.request = request;
	}
	public ResponseUtil getResponse() {
		return response;
	}
	public void setResponse(ResponseUtil response) {
		this.response = response;
	}
}
